const winston = require('winston');
const DailyRotateFile = require('winston-daily-rotate-file');
const path = require('path');
const fs = require('fs');
const config = require('./config');

// 确保日志目录存在
const logDir = path.join(process.cwd(), 'logs');
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir, { recursive: true });
}

// 自定义日志格式
const logFormat = winston.format.combine(
  winston.format.timestamp({
    format: 'YYYY-MM-DD HH:mm:ss.SSS'
  }),
  winston.format.errors({ stack: true }),
  winston.format.json(),
  winston.format.printf(({ timestamp, level, message, stack, ...meta }) => {
    let log = `${timestamp} [${level.toUpperCase()}]`;
    
    // 添加进程信息
    log += ` [PID:${process.pid}]`;
    
    // 添加请求ID（如果存在）
    if (meta.requestId) {
      log += ` [REQ:${meta.requestId}]`;
    }
    
    // 添加用户ID（如果存在）
    if (meta.userId) {
      log += ` [USER:${meta.userId}]`;
    }
    
    // 添加消息
    log += ` ${message}`;
    
    // 添加堆栈信息（错误时）
    if (stack) {
      log += `\n${stack}`;
    }
    
    // 添加额外的元数据
    const metaKeys = Object.keys(meta).filter(key => 
      !['requestId', 'userId', 'timestamp', 'level', 'message', 'stack'].includes(key)
    );
    
    if (metaKeys.length > 0) {
      const metaData = {};
      metaKeys.forEach(key => {
        metaData[key] = meta[key];
      });
      log += ` ${JSON.stringify(metaData)}`;
    }
    
    return log;
  })
);

// 控制台格式（开发环境）
const consoleFormat = winston.format.combine(
  winston.format.timestamp({
    format: 'HH:mm:ss.SSS'
  }),
  winston.format.errors({ stack: true }),
  winston.format.colorize(),
  winston.format.printf(({ timestamp, level, message, stack, ...meta }) => {
    let log = `${timestamp} ${level}`;
    
    // 添加请求ID（如果存在）
    if (meta.requestId) {
      log += ` [${meta.requestId}]`;
    }
    
    log += ` ${message}`;
    
    // 添加堆栈信息（错误时）
    if (stack) {
      log += `\n${stack}`;
    }
    
    return log;
  })
);

// 创建传输器数组
const transports = [];

// 控制台传输器
if (config.logging.console.enabled) {
  transports.push(
    new winston.transports.Console({
      level: config.logging.level,
      format: config.env === 'development' ? consoleFormat : logFormat,
      handleExceptions: true,
      handleRejections: true
    })
  );
}

// 文件传输器
if (config.logging.file.enabled) {
  // 应用日志
  transports.push(
    new DailyRotateFile({
      filename: path.join(logDir, 'app-%DATE%.log'),
      datePattern: config.logging.file.datePattern,
      maxSize: config.logging.file.maxsize,
      maxFiles: config.logging.file.maxFiles,
      level: config.logging.level,
      format: logFormat,
      handleExceptions: true,
      handleRejections: true
    })
  );
  
  // 错误日志
  transports.push(
    new DailyRotateFile({
      filename: path.join(logDir, 'error-%DATE%.log'),
      datePattern: config.logging.file.datePattern,
      maxSize: config.logging.file.maxsize,
      maxFiles: config.logging.file.maxFiles,
      level: 'error',
      format: logFormat,
      handleExceptions: true,
      handleRejections: true
    })
  );
  
  // 访问日志
  transports.push(
    new DailyRotateFile({
      filename: path.join(logDir, 'access-%DATE%.log'),
      datePattern: config.logging.file.datePattern,
      maxSize: config.logging.file.maxsize,
      maxFiles: config.logging.file.maxFiles,
      level: 'info',
      format: logFormat
    })
  );
}

// 创建logger实例
const logger = winston.createLogger({
  level: config.logging.level,
  format: logFormat,
  transports,
  exitOnError: false,
  
  // 默认元数据
  defaultMeta: {
    service: config.app.name,
    version: config.app.version,
    environment: config.env
  }
});

// 创建专用的访问日志记录器
const accessLogger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new DailyRotateFile({
      filename: path.join(logDir, 'access-%DATE%.log'),
      datePattern: config.logging.file.datePattern,
      maxSize: config.logging.file.maxsize,
      maxFiles: config.logging.file.maxFiles
    })
  ]
});

// 创建专用的SQL日志记录器
const sqlLogger = winston.createLogger({
  level: 'debug',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new DailyRotateFile({
      filename: path.join(logDir, 'sql-%DATE%.log'),
      datePattern: config.logging.file.datePattern,
      maxSize: config.logging.file.maxsize,
      maxFiles: config.logging.file.maxFiles
    })
  ]
});

// 扩展logger功能
logger.request = (req, res, responseTime) => {
  const logData = {
    method: req.method,
    url: req.originalUrl || req.url,
    statusCode: res.statusCode,
    responseTime: `${responseTime}ms`,
    userAgent: req.get('User-Agent'),
    ip: req.ip || req.connection.remoteAddress,
    requestId: req.requestId,
    userId: req.user?.id
  };
  
  if (res.statusCode >= 400) {
    logger.warn('HTTP Request', logData);
  } else {
    logger.info('HTTP Request', logData);
  }
  
  // 同时记录到访问日志
  accessLogger.info('Access Log', logData);
};

logger.sql = (sql, duration, options = {}) => {
  const logData = {
    sql: sql.replace(/\s+/g, ' ').trim(),
    duration: `${duration}ms`,
    ...options
  };
  
  if (config.env === 'development') {
    logger.debug('SQL Query', logData);
  }
  
  sqlLogger.debug('SQL Log', logData);
};

logger.performance = (operation, duration, metadata = {}) => {
  const logData = {
    operation,
    duration: `${duration}ms`,
    ...metadata
  };
  
  if (duration > 1000) {
    logger.warn('Slow Operation', logData);
  } else {
    logger.debug('Performance', logData);
  }
};

logger.security = (event, details = {}) => {
  logger.warn('Security Event', {
    event,
    ...details,
    timestamp: new Date().toISOString()
  });
};

logger.business = (event, details = {}) => {
  logger.info('Business Event', {
    event,
    ...details,
    timestamp: new Date().toISOString()
  });
};

// 错误处理
logger.on('error', (error) => {
  console.error('Logger error:', error);
});

// 文件轮转事件
if (config.logging.file.enabled) {
  transports.forEach(transport => {
    if (transport instanceof DailyRotateFile) {
      transport.on('rotate', (oldFilename, newFilename) => {
        logger.info('Log file rotated', { oldFilename, newFilename });
      });
      
      transport.on('archive', (zipFilename) => {
        logger.info('Log file archived', { zipFilename });
      });
      
      transport.on('logRemoved', (removedFilename) => {
        logger.info('Log file removed', { removedFilename });
      });
    }
  });
}

// 创建子logger
logger.child = (defaultMeta) => {
  return logger.child(defaultMeta);
};

// 获取日志统计信息
logger.getStats = () => {
  const stats = {
    level: logger.level,
    transports: logger.transports.length,
    logDir,
    files: []
  };
  
  try {
    const files = fs.readdirSync(logDir);
    stats.files = files.map(file => {
      const filePath = path.join(logDir, file);
      const stat = fs.statSync(filePath);
      return {
        name: file,
        size: stat.size,
        created: stat.birthtime,
        modified: stat.mtime
      };
    });
  } catch (error) {
    logger.error('获取日志文件统计失败:', error);
  }
  
  return stats;
};

// 清理旧日志文件
logger.cleanup = (daysToKeep = 30) => {
  try {
    const files = fs.readdirSync(logDir);
    const cutoffDate = new Date();
    cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);
    
    let removedCount = 0;
    
    files.forEach(file => {
      const filePath = path.join(logDir, file);
      const stat = fs.statSync(filePath);
      
      if (stat.mtime < cutoffDate) {
        fs.unlinkSync(filePath);
        removedCount++;
        logger.info('Removed old log file', { file, age: Math.floor((Date.now() - stat.mtime) / (1000 * 60 * 60 * 24)) });
      }
    });
    
    logger.info('Log cleanup completed', { removedCount, daysToKeep });
    
    return removedCount;
  } catch (error) {
    logger.error('Log cleanup failed:', error);
    return 0;
  }
};

// 生产环境下定期清理日志
if (config.env === 'production') {
  setInterval(() => {
    logger.cleanup(30); // 保留30天的日志
  }, 24 * 60 * 60 * 1000); // 每天执行一次
}

module.exports = logger;